package com.salt.modules.sys.app;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.salt.common.config.properties.SaltProperites;
import com.salt.common.json.AjaxJson;
import com.salt.common.utils.StringUtils;
import com.salt.core.oss.OssTemplate;
import com.salt.core.oss.model.SaltFile;
import com.salt.core.persistence.Page;
import com.salt.core.web.BaseController;
import com.salt.modules.sys.entity.Menu;
import com.salt.modules.sys.entity.MultiTenant;
import com.salt.modules.sys.entity.Office;
import com.salt.modules.sys.entity.User;
import com.salt.modules.sys.service.MultiTenantService;
import com.salt.modules.sys.service.OfficeService;
import com.salt.modules.sys.service.UserService;
import com.salt.modules.sys.utils.DictUtils;
import com.salt.modules.sys.utils.MenuUtils;
import com.salt.modules.sys.utils.RouterUtils;
import com.salt.modules.sys.utils.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.Collator;
import java.util.*;

/**
 * 用户Controller
 * @author salt
 * @version 2020-8-29
 */
@RestController
@RequestMapping("/app/sys/user")
@Api(tags ="用户管理")
public class AppUserController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private OfficeService officeService;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private MultiTenantService multiTenantService;

    @ModelAttribute
    public User get(@RequestParam(required = false) String id) {
        if (StringUtils.isNotBlank(id)) {
            User user = userService.get(id);
            if (user != null) {
                if (StringUtils.isNotBlank(user.getPhoto())) {
                    user.setPhoto(ossTemplate.outerFileLink(user.getPhoto()));
                }
            }
            return user;
        } else {
            return new User();
        }
    }

    @GetMapping("list")
    public AjaxJson list(User user, HttpServletRequest request, HttpServletResponse response) {
        User currUser = UserUtils.getUser();
        if (!(user.getOffice() != null && StringUtils.isNotBlank(user.getOffice().getId())) &&
                !(user.getCompany() != null && StringUtils.isNotBlank(user.getCompany().getId()))) {
            if (!currUser.isAdmin()) { // 是不是超级管理员
                MultiTenant multiTenant = multiTenantService.find(new MultiTenant(currUser));
                if (multiTenant != null) {  // 是不是具有多租户权限
                    user.setTenantIds(multiTenant.getTenanIds());
                } else {  // 不是超级管理员也不具有租户权限
                    user.setCompany(currUser.getCompany());
                }
            }
        }
        Page<User> page = userService.findPage(new Page<User>(request, response), user);
        return AjaxJson.success().put("page", page);
    }

    @GetMapping("currUser")
    public AjaxJson currUser() {
        User user = userService.get(UserUtils.getUser().getId());
        user.setOffice(officeService.get(user.getOffice().getId()));
        return AjaxJson.success().put("currUser", user);
    }

    /**
     * 用户头像显示编辑保存
     *
     * @return
     * @throws IOException
     * @throws IllegalStateException
     */
    @PostMapping("imageUpload")
    @ApiOperation(value = "上传头像")
    public AjaxJson imageUpload(@RequestParam("file")MultipartFile file) throws IllegalStateException, IOException {
        User currentUser = UserUtils.getUser();
        String fileLink = "";
        // 判断文件是否为空
        if (!file.isEmpty()) {
            /*if (StringUtils.isNotBlank(currentUser.getPhoto())) {
                ossTemplate.removeFile(currentUser.getPhoto());
            }*/
            SaltFile saltFile = ossTemplate.putFile(file);
            currentUser.setPhoto(saltFile.getName());
            userService.updateUserInfo(currentUser);
            fileLink = ossTemplate.outerFileLink(saltFile.getName());
        }
        return AjaxJson.success("上传成功!").put("path", fileLink);
    }

    /**
     * 返回用户信息
     *
     * @return
     */
    @GetMapping("info")
    @ApiOperation(value = "获取当前用户信息")
    public AjaxJson infoData() {
        User user = UserUtils.getUser();
        if (user != null && StringUtils.isNotBlank(user.getPhoto())) {
            user.setPhoto(ossTemplate.outerFileLink(user.getPhoto()));
        }
        return AjaxJson.success("获取个人信息成功!").put("role", UserUtils.getRoleList()).put("user", user);
    }


    @PostMapping("savePwd")
    @ApiOperation(value = "修改密码")
    public AjaxJson savePwd(String oldPassword, String newPassword, Model model) {
        User user = UserUtils.getUser();
        if (StringUtils.isNotBlank(oldPassword) && StringUtils.isNotBlank(newPassword)) {
            if (saltProperites.isDemoMode()) {
                return AjaxJson.error("演示模式，不允许操作！");
            }
            if (UserService.validatePassword(oldPassword, user.getPassword())) {
                userService.updatePasswordById(user.getId(), user.getLoginName(), newPassword);
                return AjaxJson.success("修改密码成功！");
            } else {
                return AjaxJson.error("修改密码失败，旧密码错误！");
            }
        }
        return AjaxJson.error("参数错误！");
    }

    /**
     * 获取机构JSON数据。
     * @return
     */
    //@RequiresPermissions("user")
    @GetMapping("treeData")
    public AjaxJson treeData(){
        List<Office> list = UserUtils.getOfficeAllList ();
        List rootTree = getRootTree(list);
        return AjaxJson.success().put("treeData",rootTree);
    }

    private List<Map> getRootTree(List<Office> list) {
        List<Map> offices = Lists.newArrayList();
        User user = UserUtils.getUser();
        List<Office> rootTrees = new ArrayList<>();
        if (user.isAdmin()) {  // 超级管理员
            rootTrees = officeService.getChildren("0");
        } else if (multiTenantService.isMultiTenant(user)) {   // 具有多租户权限的
            rootTrees = multiTenantService.findTenants(new MultiTenant(user));
        } else {  // 其他普通用户
            rootTrees.add(officeService.get(user.getCompany().getId()));
        }
        //List<Office> rootTrees = officeService.getChildren("0");
        for (Office root:rootTrees){
            if (SaltProperites.YES.equals(root.getUseable())) {
                offices.add(getChildOfTree(root, list));
            }
        }
        return offices;
    }

    private  Map getChildOfTree(Office officeItem,  List<Office> officeList) {
        Map oMap = new HashMap ();
        oMap.put ("id","o_" + officeItem.getId ());
        oMap.put ("type", "office");
        oMap.put ("label", officeItem.getName ());
        List children = Lists.newArrayList ();
        oMap.put ("children",children);
        List<User> list = userService.findUserByOfficeId(officeItem.getId());
        /*实现按用户姓名的首字母进行排序*/
        // Collator 类是用来执行区分语言环境的 String 比较的，这里选择使用CHINA
        Comparator comparator = Collator.getInstance(Locale.CHINA);
        Collections.sort(list, ((o1, o2) -> comparator.compare(o1.getName(),o2.getName())));

        for (int i = 0; i < list.size(); i++) {
            User e = list.get(i);
            Map<String, Object> map = Maps.newHashMap();
            map.put("id",   e.getId());
            map.put ("type", "user");
            map.put("label", e.getName());
            children.add(map);
        }
        for (Office child : officeList) {
            if (SaltProperites.YES.equals(child.getUseable())) {
                if (child.getParentId().equals(officeItem.getId())) {
                    children.add(getChildOfTree (child, officeList));
                }
            }
        }
        return oMap;
    }


    @GetMapping("getMenus")
    //@RequiresPermissions("user")
    public AjaxJson getMenus(Office office) {
        Map map = multiTenantService.getTenant(office);
        String tenant = (String) map.get("tenant");
        List<String> tenantIds = (List<String>) map.get("tenantIds");
        AjaxJson j = new AjaxJson();
        j.put("dictList", DictUtils.getDictMap());
        j.put("permissions", this.getPermissions(new Menu(tenant, tenantIds, "1")));
        j.put("menuList", MenuUtils.getMenus(new Menu(tenant, tenantIds, "1")));
        j.put("routerList", RouterUtils.getRoutersByMenu(new Menu(tenant, tenantIds, "1")));
        return j;
    }

    @PostMapping("withoutcode")
    public AjaxJson updateFreeCodeLogin(User user) {
        userService.updateFreeCodeLogin(user);
        return AjaxJson.success("设置成功!");
    }


    private Set<String> getPermissions(Menu menu) {
        List<Menu> list = UserUtils.getMenuList(menu);
        Set<String> permissions = new HashSet<>();
        for (Menu menuItem : list) {
            if (StringUtils.isNotBlank(menuItem.getPermission())) {
                // 添加基于Permission的权限信息
                for (String permission : StringUtils.split(menuItem.getPermission(), ",")) {
                    permissions.add(permission);
                }
            }
        }
        return permissions;
    }

}
